package com.code.pattern.singleton;

import com.code.pattern.singleton.enums.EnumSingleton;
import com.code.pattern.singleton.inner.LazyInnerClassSingleton;

import java.lang.reflect.Constructor;

/**
 * @author: liyufei
 * @date: 2021-03-17 20:20
 */
public class SingletonTest {

    public static void main(String[] args) throws Exception {
        // 反射破坏单例 - 以內部类模式举例
        // damageSingle();


        // 枚举单例测试
        enumSingle();
    }

    private static void enumSingle() {
        EnumSingleton e1 = EnumSingleton.INSTANCE;
        e1.print();

        EnumSingleton e2 = EnumSingleton.INSTANCE;
        e2.print();

        EnumSingleton e3 = EnumSingleton.INSTANCE;
        e3.print();

        EnumSingleton e4 = EnumSingleton.INSTANCE;
        e4.print();

        // 执行结果：发现构造器方法只被调用了一次

    }

    /**
     * 反射破坏单例 - 以內部类模式举例
     */
    private static void damageSingle() throws Exception {
        //很无聊的情况下，进行破坏
        Class<?> clazz = LazyInnerClassSingleton.class;

        //通过反射拿到私有的构造方法
        Constructor c = clazz.getDeclaredConstructor(null);
        // 强制访问，强吻，不愿意也要吻
        c.setAccessible(true);
        //暴力初始化
        Object o1 = c.newInstance();

        //调用了两次构造方法，相当于 new 了两次
        //犯了原则性问题

        Object o2 = c.newInstance();

        // 运行结果为 false【解决办法，在构造器里面判断是否重复创建，是的话直接抛出异常】
        System.out.println(o1 == o2);
    }
}
